#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         TabBar.py
#
# Copyright:    Copyright (c) 2007, Faulkner Technologies
#
# Author:       James Davies
#
# Description:  This file defines the TabBar class, a simple
#               Element container that may be used to define toolbars for
#               Assessment Editor pages and other components that
#               require toolbars.
#               
#               Perhaps in the future other pages, like the user
#               admin will use instances of this class to manage 
#               their tools.
#
# See Also:     Element
#####################################################################
#####################################################################
## Knowledge Engine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.Core import *
from Products.KnowledgeEngine.Element import Element, ElementInfo
from Products.KnowledgeEngine.PropertyDefinition import PropertyDefinition
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyTypes import *
from Products.KnowledgeEngine.PropertyStructures import *
#####################################################################
## Zope Library Imports
from Globals import DTMLFile
from App.ImageFile import ImageFile

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## TabBarInfo Class Definition
class TabBarInfo(ElementInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """
    
    #---------------------------------------------------------------#
    
    def getClassName(self):
        """
            Returns the name of the class for which 
            we are providing information.
        """
        return "TabBar"
    #---------------------------------------------------------------#
    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "Tab Bar"
        
    #---------------------------------------------------------------#
    def getIdentityType(self):
        """
            Return the identity type.  
        """
        
        return "toolbar"
        
    #---------------------------------------------------------------#
    
    def getClassIcon(self):
        """
            Return the appropriate icon file for the class.
        """
        
        return ImageFile('skins/TabBar_icon.gif', globals())
    #---------------------------------------------------------------#
    def isContainer(self):
        """
            Returns if the instance is providing folderish/container
            services.
            
            Override an return true if the instance is to be
            a container for other instances.
            
            NOTE: all instances support "events" so there is no
            need to return true if you require "event" support.
        """
        #toolbars are containers for tools
        return true
        
    #---------------------------------------------------------------#
    def isPermittedInContainer(self, containerClassInfo, containerInstance = None, instance=None):
        """
            ABSTRACT: Returns if class instances (instance) is permitted in 
            the specified container (containerInstance)
            
            NOTE: This is from this class' instance perspective.
        """
        
        #DEFAULT RULE: TabBars are only permitted in Models (as long as there isn't already a toolbar in existance)
        return containerClassInfo.isInstanceOf('Model') and ((containerInstance != None and len(containerInstance.getChildrenByInstanceOf("TabBar")) == 0) or containerInstance == None)
    #---------------------------------------------------------------#
    def isChildPermitted(self, childClassInfo, childInstance = None):
        """
            Returns if the specified child is permitted as a 
            child of the class' instances.
            
            NOTE: This is from this class' instance perspective.
            
            For component containers, this always overrides what the
            return value from childClassInfo.isPermittedInContainer(...)
        """ 
        
        #DEFAULT RULE: TabBars may have TabBarTools as children
        return childClassInfo.isInstanceOf('TabBarTool')
    
    #---------------------------------------------------------------#
    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """
        #initialise the super-class properties for reflection
        ElementInfo.onConfigureProperties(self)
        
        #add the 'showif' property
        self.addPropertyDefinition(PropertyDefinition(identity="showif", displayName="Show If...", description="The Knowledge Engine Rule Language Expression (KERL) that defines when this tab should be displayed", defaultValue="", propertyType=pt_STRING, propertyFormat=pf_TEXT_MULTILINE, propertyStructure=ps_ATOMIC))         
        
        self.addPropertyDefinition(PropertyDefinition(identity="hideDefaultTab", displayName="Hide default tab", 
                description="Should the default Assessment tab be displayed?", 
                defaultValue=False, 
                propertyType=pt_BOOLEAN, propertyFormat=pf_CHECKBOX))                 
      
       
    #---------------------------------------------------------------#
#####################################################################
## TabBar Class Definition
class TabBar(Element):
    """
        A class to represent a toolbar
    """
    #---------------------------------------------------------------#
    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = TabBarInfo()
    #---------------------------------------------------------------#
    # Custom zope manage_preview to permit previews of components.
    preview_html = DTMLFile('index_html', globals())
    #---------------------------------------------------------------#
    def __init__(self, id, identity):
        "Constructor for the TabBar"        
        Element.__init__(self, id, identity)
        
        #perform onAfterInstanciation processing
        self.onAfterInstanciation()
    #---------------------------------------------------------------#
    def onAfterInstanciation(self):
        """
            Handle Knowledge Engine specific actions after this object 
            has been loaded into memory.  
            
            This is useful for performing backwards compatibility
        """        
        
        #perform default processing
        Element.onAfterInstanciation(self)
                
    #---------------------------------------------------------------#
    def isDisplayedBeforeComponents(self):
        """
            Returns if the Element is to be displayed before
            components in a model. Alternatively the Element is
            displayed after the components in a model.
            (If the element is in a model)
        """
        
        #TabBars are displayed before 
        return true
    #---------------------------------------------------------------#
    def getTools(self):
        """
            Returns a sequence of the tools (TabBarTool)
            in this container, sorted by the TabBarTool.getOrder()
        """
        #get the immediate children of the container
        children = self.objectValues()
        #filter the Tool(s) only
        tools = [x for x in children if x.isInstanceOf("TabBarTool")]
        
        #sort the component by TabBarElement.getOrder()
        tools.sort(lambda x, y : -(x.getOrder() < y.getOrder()))
        return tools                    
        
    #---------------------------------------------------------------#
    
    def isHideDefaultTab(self):
        """ Returns whether the default tab should be hidden """
        
        return getattr(self.aq_explicit, 'hideDefaultTab', False)
    
    
    
    #---------------------------------------------------------------#
    def getContent(self, contentZone, forGenericObject = None, assessment = None):
        """
            Return the Element generated 
            content for the specified contentZone (a string).   
            This method is called by the Model.index_html dtml file
            to customise the appearance of the output.
            
            By overriding this method, Elements have the opportunity
            to perform customization of the output from a Model
            during the assessment process.
        """

        # Should we generate this TabBar
        if contentZone != "TABBAR":
            return

        #get the tools sorted in display order
        tools = self.getTools()

        #are there any tools?
        result = ""             # The result for the content zone
        tabSelected = False     # Tracks whether abother tool is selected
        if len(tools) > 0:
            for tool in tools:
                # Output the tool
                result += tool.getContent(contentZone, forGenericObject, assessment=assessment)
                if tool.isSelected(self.REQUEST):
                    tabSelected = True

        # If no other tab is selected, then we make the default 'assessment' tab selected.
        defaultTab = ""
        if not self.isHideDefaultTab():                    
            klass = tabSelected and 'plain' or 'selected'
            defaultTab = """
                  <li class='%s visualIEFloatFix' style="line-height: 1.2">
                    <a href="javascript:navigateToPage(getFirstPage())">Assessment</a>
                   </li>
            """ % klass 

        if (defaultTab != "") or (result != ""):
            result = '<div class="visualIEFloatFix" style="line-height: 1.2"><ul style="line-height: 1.2" class="contentViews visualIEFloatFix">' + defaultTab + result + "</ul></div>"

        return result
        
    #---------------------------------------------------------------#
    def isInModel(self):
        """
            Return if the toolbar is in a model
        """
        
        return self.getParentByInstanceOf("Model") != None and not self.isInReport()
        
    #---------------------------------------------------------------#
    def isInReport(self):
        """
            Return if the toolbar is in a report
        """
        
        return self.getParentByInstanceOf("Report") != None
        
    #---------------------------------------------------------------#
    def isPreviewPermitted(self):
        """
            Return if the Element is allowed to be previewed.
            
            By default all elements can't be previewed, some however
            should can be previewed. eg: HTMLHeaderFooters
        """
        
        return true
            
    #---------------------------------------------------------------#
    def isOrderedContainer(self):
        """
            Return if the children of the object may use ordering.
            
            This is to allow the 'Order' column in the Content
            management tab in Zope            
        """
        return true
        
    #---------------------------------------------------------------#
#####################################################################
## Class Initialisation
# Register Class Information with the Knowledge Engine
registerGenericObjectClass(TabBar)
#####################################################################
